package Jogo {
	import Jogo.Comm.FlashSocket;
	import Jogo.Entities.Enemy;
	import Jogo.States.*;
	import Jogo.States.Phases.Phase1;
	import Jogo.States.Phases.Phase2;
	
	import com.hurlant.crypto.rsa.RSAKey;
	import com.hurlant.math.BigInteger;
	import com.hurlant.util.Hex;
	
	import flash.desktop.NativeApplication;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.MovieClip;
	import flash.display.Scene;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.geom.Point;
	import flash.net.URLRequest;
	import flash.system.System;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	
	import mx.core.UIComponent;
	import mx.core.Window;
	import mx.flash.UIMovieClip;
	
	import spark.components.Window;

	/** The starting class of the game.
	 * 
	 * @author Bruno Zumba (27/07/2011)
	 */
	public class Main extends UIMovieClip {
		/* Game size */
		public static const GAME_WIDTH 	: Number = 1024;
		public static const GAME_HEIGHT : Number = 768;
		public static const FRAME_RATE	: Number = 30;
		
		/* States of the game */
		public static const ST_MENU : int = 0;
		public static const ST_PHASE1 : int = 1;
		public static const ST_PHASE2 : int = 2;
		
		public var states : Array;
		
		private var tf:TextField = new TextField();
		
		/* The instance of this singleton */
		private static var instance : Main = null;
		
		/* The current state of the game */
		private var currState : State;
		private var menuState : MenuState;
		private var phase1State : PhaseState;
		
		private var graphicsRoot : DisplayObjectContainer;
		
		private var setaBMP:Class; //Background
		private var seta : Bitmap;
		
		public function Main(){
			//lala();
			if (instance != null){
				//Trying to reinstanciate a singleton
			}
			
			Main.instance = this;
			graphicsRoot = new MovieClip();
			this.addChild(graphicsRoot);
			currState = null;

			states = new Array(2); //amount of states that this Main sees
			states[ST_MENU] = new MenuState();
			states[ST_PHASE1] = null;
			
			setState(ST_MENU);
			
			this.addEventListener(Event.ENTER_FRAME, enterFrame);
			
		}
		public  function click(e:MouseEvent) : void{
			PhaseState.debugar();
			PhaseState.createRedefMessage();
		}
		
		public function getMousePt() : Point{
			return (new Point(mouseX, mouseY));
		}
		
		private function lala() : void{
			var publicExponent :String = "10001";
			var privateModulus :String = "ba70a1567b3ae1aa9965c7efeb728b1e1fb8c22985551a6dc44d7567b84afb956713d55884d8be59aa837079579aa1dc0b73ada8b7ddb16dd74a97ee850fdd7a0f972e3b9affebdac4ef2949bfcde335078788d5711286a2967bb1ddbe4c7d24eb7495b0dccfc8b19d280ed9c50d6930d63a6470998724cd5b268fbba8f7001b0fdc24128c0a092cacb020dd4a7005ab1f20914c58656926911709670091896f35576cbc8e09d84da2bd7746e2220161e30dc1f01393ef7da82128495b6bc267dd5cbfe5283e718fb544fa1fd88b6ffce7839e59831489ed137b5722c69ea2eda5bacb7d662c5e5747de7a20cbb94cc6f297d8b76b6c8720aa758243a6dcbc7d";
			var privateExponent :String = "7b74012146d02285d8b570c30960fb85a2f3b07dd5f01863fecc5ba5a67ee04079d4c43cad1ae8506f7c4189d7dc68b9504bf4fdf762310eceb4720e5ac5ba9e0c9ccadc653279768f58de3a1b6bb5bb7394e7a28e10fa5dc6cf79639f92fe7ae7fe76f07a068c9a2fba4abb20a454b725e3dc8642e31e176cf807ccf78136eb910158b75af7f68ab8f8e560d336f1c9be11302cd6458dc2307cef2558d3bd6eace6d82820f401c8715b067ef266739a4428b6cb0b3835a57deb98b4794a5f13cbb1b7e816c4e1d7be16c2205a27d1550cf4567e2fb7b03565fe5f2093ce00c426cae445fc328986ac1873ea431718243f08a05ddb68578ac99d85fec7fe7f81";
			var primeP :String = "f6ec507c19f528f9ed7043d3d1031ed20e576ec5eafa3babedb528569581f42abad65c8fe083bbf61663ca2fe78c612aa1b6fcc4e42c15e68032fcaf2996b7af55d966410c1115e6a1959becf4bcceb4d5a52b53508f170d2762d240e6f5cecbe963ea3f1f34843b7af498bb7d2f629073b7619cf45c9265cc81cca4b8d11fe5";
			var primeQ :String = "c14b22a7e8b4b5e5aeec3f2446cfdc33a768ccd5702a557a150d73d86c6c4df7c087b0063570930dd66048b8ba82e6e230d3ca98ebda55f5552eab061720aabd900bcfd97e555fd55837f1aedd6f5f9555d7ba3f61f081d41c66436e71f79138fb22bc9db90e0bd7db2bcf35d611e21f8470c32405e74814143efc2c491ef0b9";
			var primeExpP :String = "5e22bf98606907a328b3491882b196d96c204719eb3854f179e13bacaeb8e97634deae5127bdf135a3598de66f7724401580e6a2c57e4d27202ed00893696343d40dda9ee7d3c7aeb261901d693c65eda9199c07da4982f73fd1bbe88464a7df336e250ac581c6fbca275fe6f295d314d118d37cfbe822e3ee7079ad3ecc7345";
			var primeExpQ :String = "461c159ee7a61c500a0980c18cb9ba3a361faa2444c1e62d18d3bf5021cb8ae0314246138a70a1b6242ada55beb8da3bf2cfef2d5666e444cf37d52aa95adcf352fb25d1d2a3eed5b860da55bdd5b6cab8cf3dabddbf59a7f1011ab645ba313f84bfcdc03bae1f9794d4a81cf3df9ab029dea8b93936f18aeee905989e910d69";
			var crtCoef :String = "20452e34f0a689b8e81c41c2b1947ccc17f8b802c5dc43b2c77bf6d32dec873c862092b199d9f46fd57987067feff14e84b6a7907befbd82222a1ecf5c691bfe446741e64b710c8db85f6f49f9ca5c282efacf2da445598357a2f33e5ba816e0dd1d93373e246477d06f4aad159b8e67c95b3ee4e4a48678265ae6f14443b1da";
			
			var rsaPubSpec : RSAKey = RSAKey.parsePrivateKey(privateModulus, publicExponent, privateExponent, primeP, primeQ, primeExpP, primeExpQ, crtCoef);
			
			var msg: String = new String("Meu limão, meu limoeiro");
			
			var um:ByteArray = Hex.toArray(Hex.fromString(msg));
			var dois:ByteArray = new ByteArray();
			var tres:ByteArray = new ByteArray();
			
			rsaPubSpec.encrypt(um, dois, um.length);
			
			trace("Encriptado: "+dois.toString());
			
			rsaPubSpec.decrypt(dois, tres, dois.length);
			
			trace("Desencriptado: "+tres.toString());
		}
		
		/**
		 * Change the actual state of the game for the given state
		 * 
		 * @param state the new state. Must be one of the constants defined above
		 */
		public function setState(state : int) : void{
			var prev : State = currState;
			
			if (prev != null) {
				prev.leave();
			}
			
			if(states[state] == null){
				states[ST_PHASE1] = new Phase1();
			}
			currState = states[state];
			currState.assume(prev);
		}

		
		
		/**
		 * Return the unique instance of this singleton
		 */
		public static function getInstance() : Main{
			return instance;
		}
		
		private function enterFrame(e: Event) : void {
			currState.enterFrame(e);
		}
		
		public function addGraphics(g : DisplayObject) : void{
			if (!graphicsRoot.contains(g))
				graphicsRoot.addChild(g);
		}

		public function removeGraphics(g : DisplayObject) : void{
			if (graphicsRoot.contains(g))
				graphicsRoot.removeChild(g);
		}
		
		public function exit(ev:MouseEvent):void{
			flash.desktop.NativeApplication.nativeApplication.exit(0);
		}

		
	}
}